<template>
  <div v-loading="loading" class="cm-table">
    <!-- table -->
    <div class="cm-table_top__filter">
      <el-form :inline="true" :model="filters">
        <el-form-item>
          <el-input v-model="filters.name" :placeholder="t('thead.username')"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button icon="search" type="primary" @click="findPage">{{ t('action.search') }}</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="cm-table_top__toolbar">
      <el-button 
        icon="delete"
        v-if="showBatchDelete"
        type="danger"
        :disabled="selections.length === 0"
        @click="handleBatchDelete()"
      > {{ t('action.batchDelete') }} </el-button>

      <el-button icon="plus" type="primary">{{ t('action.add') }}</el-button>
    </div>
    <el-table 
      class="cm-table__tb"
      :data="data.content" 
      v-bind="$attrs"
      @selection-change="selectionChange"
      :header-cell-style="{background:'#F6F7FB'}"
    >
      <el-table-column
        v-for="col in columns"
        :key="col.prop"
        v-bind="col"
      >
        <template #default="{row, column}" v-if="col.type==='switch'">
          {{row[col.prop] === 1 ? t('status.on'): t('status.off') }}
          <el-switch v-model="row[col.prop]" active-value="1" inactive-value="0"></el-switch>
        </template>
      </el-table-column>
      <el-table-column
        v-if="showOperation"
        fixed="right"
        :label="t('action.operation')"
        :width="oprWidth"
      >
        <template #default="{row}">
          <template v-for="(opr, i) in operations" :key="i">
            <template v-if="isShow(opr.show, row)">
              <el-button 
                v-if="opr.type === 'edit'"
                type="text"
                :disabled="isDisabled(opr.disabled, row)"
                @click="handleEdit(row)"
              >
                <el-icon class="el-icon--left" v-if="opr.isShowIcon"><Edit /></el-icon>
                {{ t('action.edit') }} 
              </el-button>
              <el-button 
                v-else-if="opr.type==='delete'"
                type="text"
                class="danger"
                :disabled="isDisabled(opr.disabled, row)"
                @click="handleDelete(row)"
                >
                <el-icon class="el-icon--left" v-if="opr.isShowIcon"><Delete /></el-icon>
                {{t('action.delete')}}
              </el-button>
              <el-button 
                v-else
                type="text"
                :disabled="isDisabled(opr.disabled, row)"
                @click="opr.onClick(row)"
              >
              <el-icon class="el-icon--left" v-if="opr.isShowIcon"><component :is="opr.type" /></el-icon>
              {{ opr.label }} 
              </el-button>
            </template>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <!-- pagination -->
    <div class="cm-table_bottom__toolbar">
      <el-pagination 
        hide-on-single-page
        class="cm-table__pagination"
        v-if="showPagination"
        v-model:currentPage="pageRequest.pageNum"
        v-model:page-size="pageRequest.pageSize"
        :page-sizes="[20, 50, 100]"
        layout="total, prev, pager, next, sizes "
        :total="data.totalSize || 0"
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script setup>
import { ElMessage, ElMessageBox } from 'element-plus';
import { isShallow } from 'vue';

const props = defineProps({
  getPage: Function,
  filters: Object,
  columns: Array,
  showPagination: {
    type: Boolean,
    default: true
  },
  showOperation: {
    type: Boolean,
    default: true,
  },
  operations: {
    type: Array,
    default: () => {
      return [
        {type: 'edit', isShowIcon: false},
        {type: 'delete', isShowIcon: false}
      ];
    }
  },
  oprWidth: {
    type: Number,
    default: 185
  },
  showBatchDelete: {
    type: Boolean,
    default: true,
  }
});

const emit = defineEmits(['handleEdit', 'handleDelete']);
const { t } = useI18n();
const loading = ref(false);
const switchStatus = ref(false);
const pageRequest = reactive({
  pageNum: 1,
  pageSize: 20,
});
const data = ref({});
function getSwitchStatus(status) {
}

function findPage() {
  if(!props.getPage) {
    return;
  }
  loading.value = true;
  const req = props.getPage({
    ...pageRequest,
    ...(props.filters||{}),
    sortby: props.sortby
  });
  if(Object(req).constructor === Promise) {
    req.then(res => {
      if(res.data instanceof Array) {
        data.value = {
          content: res.data,
          totalSize: res.data.length
        };
      } else {
        data.value = res.data;
      }
    }).catch(() => {
      data.value = {}
    }).finally(() => {
      loading.value = false;
    });
  }
}

function reload(){
  handlePageChange(1);
}

function handleSizeChange(pageSize){
  pageRequest.pageSize = pageSize;
  pageRequest.pageNum = 1;
  findPage();
}

function handlePageChange(pageNum){
  pageRequest.pageNum = pageNum;
  findPage();
}

reload();
defineExpose({
  refresh: findPage,
  reload,
})

function isShow(showFn, row) {
  if(showFn && typeof showFn === 'function'){
    return showFn(row);
  }
  return true;
}

function isDisabled(disabledFn, row) {
  if(disabledFn && typeof disabledFn === 'function'){
    return disabledFn(row);
  }
  return false;
}
// edit
function handleEdit(row) {
  emit('handleEdit', row);
}
function handleDelete(row) {
  onDelete(row.id);
}

const selections = ref([]);
function selectionChange(slts) {
  selections.value = slts;
}
function handleBatchDelete() {
  let ids = selections.value.map((item) => item.id).toString();
  onDelete(ids);
}

function onDelete(ids) {
  ElMessageBox.confirm(t('tips.deleteConfirm'), t('tips.deleteTitle'), {
    onfirmButtonText: t('action.confirm'),
    cancelButtonText: t('action.cancel'),
    type: 'warning',
    draggable: true
  }).then(() => {
    const callback = () =>  {
      ElMessage({message: t('tips.success'), type: 'success'});
      reload();
    };
    emit('handleDelete', ids, callback);
  }).catch(() => {});
}
</script>


<style lang="scss" scoped>
.cm-table__tb {
  width: 100%;
  padding-left: 15px;
  padding-right: 15px;
}
.cm-table_top__filter {
  padding: 15px 20px;
  display: flex;
  background: #fff;
}
.cm-table_top__toolbar {
  margin-top: 20px;
  padding: 15px 20px;
  display: flex;
  background: #fff;
}
.cm-table_bottom__toolbar {
  background: #fff;
  padding: 10px 20px;
  &:after {
    content: '';
    display: table;
    clear: both;
  }
}
.cm-table__pagination {
  float: right;
  padding-right: 0;
}
.danger {
  color: var(--el-color-danger) !important;
}
</style>

